/**
 * @Author: lena
 * @Description:数组
 * @Version: 1.0.0
 * @Date: 2021/8/24 20:45
 */

package datatype

import (
	"encoding/json"
	"fmt"
	"strconv"
)

func Array1() {
	// 方式一：定义固定的数组长度
	var array1 [5]int
	fmt.Println(array1) // [0 0 0 0 0]
	// 方式二：定义并赋值
	var array2 = [5]int{1, 2, 3, 4, 5}
	fmt.Println(array2) // [1 2 3 4 5]
	// 方式三：定义并赋值
	array3 := [3]int{1, 2, 3}
	fmt.Println(array3) // [1 2 3]

	// 查看数组类型：不同长度的固定数组，不是同种类型
	fmt.Printf("%T", array1) // [5]int

	Array2(array1) // 成功调用
	//Array2(array3)	// 报错：不能从[3]int->[5]int
}

func Array2(array [5]int) {
	fmt.Println(array)
}

func Array3() {
	array := [3]int{1, 2, 3}
	fmt.Println("before:", array) // before: [1 2 3]
	method(array)
	fmt.Println("result:", array) // result: [1 2 3]
}

func method(array [3]int) {
	array[0] = 10
	fmt.Println("in:", array) // in: [10 2 3]
}

// Array4 slice
func Array4() {
	array1 := []int{1, 2, 3, 4, 5} // 不指定数组长度
	//fmt.Printf("%T",array1)	// 类型：[]int

	fmt.Println(array1) // [1 2 3 4 5]
	method2(array1)
	fmt.Println(array1) // [1 2 10 4 5]
}

func method2(array []int) {
	// 引用传递：实际值会被改变
	array[2] = 10
}

func Array5() {
	// 方式一：有初始化值
	array1 := []int{1, 2, 3}
	fmt.Printf("%d,%v", len(array1), array1) // 3,[1 2 3]
	// 方式二：定义一个切片，利用make分配空间
	var array2 []int
	array2 = make([]int, 3)
	fmt.Printf("%d,%v", len(array2), array2) // 3,[0 0 0]
	// 方式三：定义一个切片同时分配空间
	var array3 []int = make([]int, 5)
	fmt.Printf("%d,%v", len(array3), array3) // 5,[0 0 0 0 0]
	// 方式四：利用符号:=自动匹配出这是一个切片
	array4 := make([]int, 5)
	fmt.Printf("%d,%v", len(array4), array4) // 5,[0 0 0 0 0]
}

func Array6() {
	array1 := []int{1, 2, 3}
	fmt.Printf("%d,%d,%v\n", len(array1), cap(array1), array1) // 3,3,[1 2 3]
	array1 = append(array1, 2)                                 // 追加元素2
	fmt.Printf("%d,%d,%v\n", len(array1), cap(array1), array1) // 4,6,[1 2 3 2]

	array2 := make([]int, 5, 7)
	fmt.Printf("%d,%d,%v\n", len(array2), cap(array2), array2) // 5,7,[0 0 0 0 0]
	array2 = append(array2, 1, 2, 3, 4)                        // 追加4个元素
	fmt.Printf("%d,%d,%v\n", len(array2), cap(array2), array2) // 9,14,[0 0 0 0 0 1 2 3 4]
}

func Array7() {
	array1 := []int{0, 1, 2, 3, 4, 5, 6, 7}
	// 截取索引[start,end)
	array2 := array1[0:3]
	fmt.Println(array2) // [0 1 2]
}

func Array8() {
	array1 := []int{0, 1, 2, 3, 4, 5, 6, 7}
	array2 := array1[0:3] // [0 1 2]
	// 修改截取数组的值
	array2[0] = 100
	// 原来数组的值也改变了
	fmt.Println(array1) // [100 1 2 3 4 5 6 7]
	fmt.Println(array2) // [100 1 2]
}

func Array9() {
	array1 := []int{0, 1, 2, 3, 4, 5, 6, 7}
	// 遍历输出：index是索引，value是值
	for index, value := range array1 {
		fmt.Println(index, value)
	}
	// 遍历输出：忽略index值
	for _, value := range array1 {
		fmt.Println(value)
	}
}

// Array10 数组[start:end] ==> [start,end)
func Array10() {
	// 定义slice切片
	array := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	fmt.Println(array)
	// 截取其中部分数组:从第0个开始,截取到索引4,不包括4
	s1 := array[0:4]
	fmt.Println(s1)
}

// Array11 截取slice获得的变量指向同一数组空间
func Array11() {
	array := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	fmt.Println(array) // [0 1 2 3 4 5 6 7 8 9 10]
	s1 := array[3:8]
	fmt.Println(s1) // [3 4 5 6 7]
	fmt.Println("-----------------------")
	s1[2] = 100
	fmt.Println(array) // [0 1 2 3 4 100 6 7 8 9 10]
	fmt.Println(s1)    // [3 4 100 6 7]
}

// Array12 截取后数组的容量=起始索引到最后一个索引的位置
func Array12() {
	array := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	fmt.Println(len(array), cap(array)) // 11 11
	s := array[:6]
	fmt.Println(len(s), cap(s)) // 6 11
	s1 := array[3:8]
	fmt.Println(len(s1), cap(s1)) // 5 8
}

// Array13 slice未初始化空间使用问题
func Array13() {
	a := [][]int{}
	// a[0][0]=1 // panic: runtime error: index out of range [0] with length 0
	a = make([][]int, 4)
	// a[0][0]=1   // panic: runtime error: index out of range [0] with length 0
	b := []int{1, 2, 3}
	a[0] = b
	c := []int{4, 5, 6, 7, 8}
	a[1] = c
	fmt.Println(a) // [[1 2 3] [4 5 6 7 8] [] []]
}

// Array14 数组赋值另一数组
func Array14() {
	a := [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
	expert := [][]int{{1, 4, 7}, {2, 5, 8}, {3, 6, 9}}
	fmt.Println(a)
	a = expert // 直接赋值
	fmt.Println(a)
	// 如果在方法体内希望全局有效，那么需要传入指针
}

// Array15 数组是值拷贝 互不影响; 切片是引用传递 会相互影响
func Array15() {
	// 数组
	a := [5]int{1, 2, 3, 4, 5}
	b := a
	fmt.Println(a) // [1 2 3 4 5]
	fmt.Println(b) // [1 2 3 4 5]
	fmt.Println("-----------------")
	b[0] = 777
	fmt.Println(a) // [1 2 3 4 5]
	fmt.Println(b) // [777 2 3 4 5]
	fmt.Println("=================")
	// 切片
	c := []int{1, 2, 3, 4, 5}
	d := c
	fmt.Println(c) // [1 2 3 4 5]
	fmt.Println(d) // [1 2 3 4 5]
	fmt.Println("-----------------")
	d[0] = 777
	fmt.Printf("%p,%v\n", c, c) // 0xc0000e20c0,[777 2 3 4 5]
	fmt.Printf("%p,%v\n", d, d) // 0xc0000e20c0,[777 2 3 4 5]
}

// Array16 删除数组第一个元素
func Array16() {
	a := []int{1, 2, 3, 4, 56, 7, 7, 8}
	fmt.Println(a[1:]) // [2 3 4 56 7 7 8]
}

// Array17 拼接两个数组
func Array17() {
	array1 := []int{1, 2, 3}
	array2 := []int{4, 5}
	for _, value := range array2 {
		array1 = append(array1, value)
	}
	fmt.Println(array1)
}

/** TansposeArray *转置数组
1 2 3				1 4 7
4 5 6		==>		2 5 8
7 8 9				3 6 9
*/

func TansposeArray(arr [][]int) [][]int {
	x := len(arr[0])
	y := len(arr)
	res := make([][]int, x)
	for i := 0; i < x; i++ {
		a := make([]int, y)
		for j := 0; j < y; j++ {
			a[j] = arr[j][i]
		}
		res[i] = a
	}
	return res
}

func Array19() {
	var list []*string
	for i := 0; i < 1000; i++ {
		str := strconv.Itoa(i)
		list = append(list, &str)
	}
	res, err := json.Marshal(list[0:50])
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(res))
}
